package com.tamir.template;

import com.tamir.template.bean.TNode;
import com.tamir.template.cache.TemplateParserCache;
import com.tamir.template.config.TemplateNodeTypeConfig;
import com.tamir.template.context.TemplateContext;
import com.tamir.template.util.SequenceLocal;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author : tanggh
 * @description :〈描述〉
 * @date : 2016/10/26
 */
public class TemplateParse
{

    private String templateText;
    private String key = null;

    public TemplateParse(String key, String template)
    {
        this.templateText = template;
        this.key = key;
    }

    public TemplateParse(String template)
    {
        this.templateText = template;
        this.key = SequenceLocal.getSeq();
    }

    /**
     * 解析模板文件,默认使用缓存
     * @return
     */
    public TNode parse()
    {
        return parse(false);
    }

    /**
     * 解析模板文件
     * @param refresh 是否强制刷新缓存
     * @return
     */
    public TNode parse(boolean refresh)
    {
        if (!refresh && TemplateParserCache.contains(this.key) && TemplateParserCache
                .getITNodeByKey(key) !=
                null)
        {
            return TemplateParserCache.getITNodeByKey(this.key);
        }
        TNode rootNode = TemplateNodeTypeConfig.getInstance().getTemplateStarter().parse(this.templateText);
        TemplateParserCache.setITNode(key, rootNode);
        return rootNode;
    }

    /**
     * 生成表达式翻译后的文本
     * @param context
     * @return
     * @throws Exception
     */
    public String generateWithContext(TemplateContext context) throws Exception
    {
        TNode node = TemplateParserCache.getITNodeByKey(key);
        return TemplateNodeTypeConfig.getInstance().getTemplateStarter().generateText(node, context);
    }

    /**
     * 获取表达式的值
     * @param context
     * @return
     * @throws Exception
     */
    public Object getExpressValue(TemplateContext context) throws Exception
    {
        TNode node = TemplateParserCache.getITNodeByKey(key);
        if(node != null && !node.getSubNodeList().isEmpty()){
            return TemplateNodeTypeConfig.getInstance().getTemplateStarter().getNodeValue(node
                    .getSubNodeList().get(0), context);
        }
        return null;
    }

    public static void main(String[] args)
    {

        int complex = 5;
        switch (complex)
        {
            case 0:
                TemplateParse.genComplex();
                break;
            case 1:
                TemplateParse.genCommon();
                break;
            case 2:
                TemplateParse.genMapObject();
                break;
            case 3:
                TemplateParse.genArrayObject();
                break;
            case 4:
                TemplateParse.genIf();
                break;
            case 5:
                TemplateParse.genIfCon();
                break;
            case 6:
                TemplateParse.genAttrExpressValue();
                break;
            case 7:
                TemplateParse.genSqlExpress();
                break;
            case 8:
                TemplateParse.genHtmlExpress();
                break;
            default:
                break;
        }

    }

    public static void genArrayObject()
    {
        String templateText = "aa${users[0].name}和${users[1]" +
                ".name}互斥<#map userMap as user>" +
                "(${user.key}, ${user.value})</#map>${user.outKey}";
        TemplateParse parse = new TemplateParse("55555", templateText);
        TNode rootNode = parse.parse();
        Map<String, String> map = new HashMap<String, String>();
        map.put("mapKey", "mapValue");
        List users = new ArrayList();
        users.add(new Product("1111", "测试1"));
        users.add(new Product("2222", "测试2"));

        TNode node = new TNode();
        node.setOutKey("it's a test outKey");
        Map<String, Object> request = new HashMap<String, Object>();
        request.put("userMap", map);
        request.put("users", users);
        request.put("user", node);
        TemplateContext context = new TemplateContext(request);
        try
        {

            System.out.println(parse.generateWithContext(context));
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    public static void genMapObject()
    {
        String templateText = "aa<#list users as user >${user['pid1'].name}和${user['pid2']" +
                ".name}互斥</#list><#map userMap as user>" +
                "(${user.key}, ${user.value})</#map>${user.outKey}";
        TemplateParse parse = new TemplateParse("55555", templateText);
        TNode rootNode = parse.parse();
        Map<String, String> map = new HashMap<String, String>();
        map.put("mapKey", "mapValue");
        Map<String, Product> map1 = new HashMap<String, Product>();
        map1.put("pid1", new Product("1111", "测试1"));
        map1.put("pid2", new Product("2222", "测试2"));

        List users = new ArrayList();
        users.add(map1);
        TNode node = new TNode();
        node.setOutKey("it's a test outKey");
        Map<String, Object> request = new HashMap<String, Object>();
        request.put("userMap", map);
        request.put("users", users);
        request.put("user", node);
        TemplateContext context = new TemplateContext(request);
        try
        {
            System.out.println(parse.generateWithContext(context));
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    public static void genComplex()
    {
        String templateText = "aa<#list users as user >夺<#map user as userMap>(${userMap.key}, " +
                "${userMap.value})</#map></#list><#map userMap as user>(${user.key}, ${user" +
                ".value})</#map>${user.outKey}";
        TemplateParse parse = new TemplateParse("55555", templateText);
        TNode rootNode = parse.parse();
        Map<String, String> map = new HashMap<String, String>();
        map.put("mapKey", "mapValue");
        Map<String, String> map1 = new HashMap<String, String>();
        map1.put("111map1", "map1value");
        map1.put("111mpa2", "map2value");

        Map<String, String> map2 = new HashMap<String, String>();
        map2.put("2222map1", "map1value");
        map2.put("2222map2", "map2value");

        List users = new ArrayList();
        users.add(map1);
        users.add(map2);
        TNode node = new TNode();
        node.setOutKey("it's a test outKey");
        Map<String, Object> request = new HashMap<String, Object>();
        request.put("userMap", map);
        request.put("users", users);
        request.put("user", node);
        TemplateContext context = new TemplateContext(request);
        try
        {
            System.out.println(parse.generateWithContext(context));
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    public static void genCommon()
    {
        String templateText = "aa<#list users as user >夺${user}</#list><#map userMap as " +
                "user>(${user.key}, ${user.value})</#map>${user.outKey}" +
                "测试数据执行失败，总行数${user.outKey}";
        TemplateParse parse = new TemplateParse("55555", templateText);
        TNode rootNode = parse.parse();
        Map<String, String> map = new HashMap<String, String>();
        map.put("mapKey", "mapValue");
        List users = new ArrayList();
        users.add("test1");
        users.add("test2");
        TNode node = new TNode();
        node.setOutKey("it's a test outKey");
        Map<String, Object> request = new HashMap<String, Object>();
        request.put("userMap", map);
        request.put("users", users);
        request.put("user", node);
        TemplateContext context = new TemplateContext(request);
        try
        {
            System.out.println(parse.generateWithContext(context));
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    public static void genIf()
    {
        String templateText = "aa${a+b}<#if (a+b)-1<1*1> a:${a/3.0} <else> b:${b} </#if>bbb";
        TemplateParse parse = new TemplateParse("55555", templateText);
        TNode rootNode = parse.parse();
        Map<String, String> map = new HashMap<String, String>();
        map.put("mapKey", "mapValue");
        TNode node = new TNode();
        node.setOutKey("it's a test outKey");
        Map<String, Object> request = new HashMap<String, Object>();
        request.put("a", 1);
        request.put("b", 1);
        TemplateContext context = new TemplateContext(request);
        try
        {
            System.out.println(parse.generateWithContext(context));
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    public static void genIfCon()
    {
        String templateText = "<#if ((a =='1.0') && (true)) ></#if>";
        TemplateParse parse = new TemplateParse("55555", templateText);
        TNode rootNode = parse.parse();
        TNode rootNode1 = parse.parse(true);

        Map<String, String> map = new HashMap<String, String>();
        map.put("mapKey", "mapValue");
        TNode node = new TNode();
        node.setOutKey("it's a test outKey");
        Map<String, Object> request = new HashMap<String, Object>();
        request.put("a", "1.0");
        request.put("b", 1);
        request.put("c", 1.0);

        TemplateContext context = new TemplateContext(request);
        try
        {
            System.out.println(parse.getExpressValue(context));
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    public static void genAttrExpressValue()
    {
        String templateText = "${(a*(b+4))/c}";
        templateText = "${( a < b ) && !( a > b )}";
//        templateText = "<#if a < b && !( a > b )></#if>";

        TemplateParse parse = new TemplateParse("55555", templateText);
        TNode rootNode = parse.parse();
        Map<String, String> map = new HashMap<String, String>();
        map.put("mapKey", "mapValue");
        TNode node = new TNode();
        node.setOutKey("it's a test outKey");
        Map<String, Object> request = new HashMap<String, Object>();
        request.put("a", 1);
        request.put("b", 2);
        request.put("c", 1.20);
        request.put("d", true);


        TemplateContext context = new TemplateContext(request);
        try
        {
            System.out.println(parse.getExpressValue(context));
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    public static void genSqlExpress()
    {
        String templateText = "select * from hbase where 1=1 a not in(${date})";
        TemplateParse parse = new TemplateParse("55555", templateText);
        TNode rootNode = parse.parse();
        Map<String, String> map = new HashMap<String, String>();
        map.put("mapKey", "mapValue");

        Map<String, Object> request = new HashMap<String, Object>();
        request.put("date", "20150403");


        TemplateContext context = new TemplateContext(request);
        try
        {
            System.out.println(parse.generateWithContext(context));
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    public static void genHtmlExpress()
    {
        String templateText = "<html><head>test</head><script src='http://www.baidu.com' " +
                "/><body>(today:${date}):it is a test html!<br/>" +
                "<#if !(a == 1) > ${a} <else> a is less than zero.</#if></body></html>";
        TemplateParse parse = new TemplateParse("55555", templateText);
        TNode rootNode = parse.parse();
        Map<String, String> map = new HashMap<String, String>();
        map.put("mapKey", "mapValue");
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Map<String, Object> request = new HashMap<String, Object>();
        request.put("date", format.format(new Date()));
        request.put("a", 1);


        TemplateContext context = new TemplateContext(request);
        try
        {
            System.out.println(parse.generateWithContext(context));
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }

    }
}
